package com.eat.view;

import com.eat.constant.OrderConstant;
import com.eat.domain.*;
import com.eat.exception.CheckException;
import com.eat.service.ItemService;
import com.eat.service.OrderItemService;
import com.eat.service.OrderService;
import com.eat.service.ShopService;
import com.eat.service.impl.ItemServiceImpl;
import com.eat.service.impl.OrderItemServiceImpl;
import com.eat.service.impl.OrderServiceImpl;
import com.eat.service.impl.ShopServiceImpl;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

public class NormalUserPage extends AbstractPage {
    private User currentUser = null;
    private OrderService orderService = new OrderServiceImpl();
    private OrderItemService orderItemService = new OrderItemServiceImpl();
    private ShopService shopService = new ShopServiceImpl();
    private ItemService itemService = new ItemServiceImpl();


    public NormalUserPage(User user) {
        currentUser = user;
        init();
    }

    @Override
    void init() {
        // 插入菜单
        menuMap.put(0, "返回首页");
        menuMap.put(1, "我要订餐");
        menuMap.put(2, "签收订单");
        menuMap.put(3, "查看订单");
        menuMap.put(4, "删除订单");
        menuMap.put(5, "退出系统");
    }

    @Override
    protected void printHeader() {
        System.out.println("欢迎 " + currentUser.getUserName() + " 使用吃货联盟订餐系统");
        System.out.println("**********************");
    }

    @Override
    protected boolean doChoose(Scanner scanner) {
        int index = scanner.nextInt();
        boolean isExit = false;
        switch (index) {
            case 0: {
                returnToIndexPage(scanner);
                isExit = true;
                break;
            }
            case 1: {
                doOrderFood(scanner);
                isExit = false;
                break;
            }
            case 2: {
                doConfirmOrder(scanner);
                isExit = false;
                break;
            }
            case 3: {
                showOrders(null, scanner);
                isExit = false;
                break;
            }
            case 4: {
                doDeleteOrder(scanner);
                isExit = false;
                break;
            }
            case 5: {
                doExit();
                isExit = true;
                break;
            }
        }
        return isExit;
    }

    // 删除用户订单
    private void doDeleteOrder(Scanner scanner) {
        // 展示用户拥有的订单
        boolean goon = false;
        do {
            boolean isContinued = showOrders(null, scanner);
            if (isContinued) {
                System.out.println("请输入你想要删除的订单编号");
                long orderId = scanner.nextLong();
                // 执行删除
                orderService.deleteByOrderId(orderId);
                System.out.println("您的订单已删除");
                System.out.println("是否继续删除(y/n)");
                if ("y".equals(scanner.next())) {
                    goon = true;
                }
            } else {
                System.out.println("您的订单空空如也");
                block(scanner);
            }
        } while (goon);
    }

    private String orderStateToString(Integer state) {
        if (OrderConstant.NOT_PAYED == state) {
            return "未支付";
        } else if (OrderConstant.PAYED_NOT_DELIVER == state) {
            return "商家准备订单中";
        } else if (OrderConstant.PAYED_ON_THE_WAY == state) {
            return "订单正在配送中";
        } else if (OrderConstant.PAYED_CHECKED == state) {
            return "订单已签收";
        }
        throw new CheckException("无此订单状态");
    }

    // 展示用户订单
    private boolean showOrders(Integer status, Scanner scanner) {
        // 获取该用户的订单
        List<Order> orderList = orderService.findByUserId(currentUser.getUserID());
        if (status != null) {
            // 执行筛选
            orderList = orderList.stream()
                    .filter(order -> order.getStatus() == status)
                    .collect(Collectors.toList());
        }
        if (orderList.size() > 0) {
            System.out.println("订单编号\t\t订单总价\t\t订单状态\t\t下单日期");
            SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:SS");
            orderList
                    .forEach(order ->
                            System.out.println(order.getOrderId() + "\t\t" + order.getPrice() +
                                    "\t\t" + orderStateToString(order.getStatus()) + "\t\t" +
                                    format.format(order.getGmtCreate())));
            block(scanner);
            return true;
        }
        return false;
    }


    // 打印输出所有商家
    private void printAllShop() {
        // 查询出所有商家
        List<Shop> shopList = shopService.findAll();
        System.out.println("商家编号\t\t商家店名\t\t商家地址");
        shopList
                .forEach(shop ->
                        System.out.println(shop.getShopId() + "\t\t" +
                                shop.getShopName() + "\t\t" + shop.getShopAddress()));
    }

    // 选择一家商店并返回
    private Shop chooseShop(Scanner scanner) {
        // 选择商家
        System.out.println("请选择商家编号");
        long shopId = scanner.nextLong();
        return shopService.findOne(shopId);
    }

    // 打印输出某商家的商品
    private void printShopItems(Shop shop) {
        // 打印该商家的商品
        List<Item> itemList = shopService.findByShopId(shop.getShopId());
        System.out.println("商品编号\t\t商品名\t\t商品价格");
        itemList.forEach(item -> System.out.println(item.getItemId() + "\t\t"
                + item.getItemName() + "\t\t" + item.getItemPrice()));
    }

    // 循环选择商品返回订单项
    private List<OrderItem> doChooseItem(Scanner scanner) {
        List<OrderItem> orderItemList = new ArrayList<>();
        boolean isContinued = true;
        do {
            System.out.println("选择您想要的商品编号");
            int itemId = scanner.nextInt();
            Item item = itemService.findOne(itemId);
            System.out.println("请输入数量");
            int count = scanner.nextInt();
            // 产生一项订单项目
            OrderItem orderItem = orderItemService.createOrderItem(item, count);
            orderItemList.add(orderItem);
            System.out.println("是否继续订餐(y,n)");
            if (!"y".equals(scanner.next())) {
                isContinued = false;
            }
        } while (isContinued);
        return orderItemList;
    }

    // 打印订单详情
    private void printOrderDetail(List<OrderItem> orderItemList) {
        // 打印订单项详情
        System.out.println("商品名\t数量\t小计");
        // 计算订单总价
        BigDecimal total = orderItemList
                .stream()
                .map(OrderItem::getItemPrice)
                .reduce(new BigDecimal(0), BigDecimal::add);
        // 打印详情
        orderItemList
                .forEach(orderItem -> {
                    Item item = itemService.findOne(orderItem.getItemId());
                    System.out.println(item.getItemName() + "\t" + orderItem.getCount() + "\t" + orderItem.getItemPrice());
                });
        System.out.println("订单总价为 " + total);

    }

    // 执行付款
    private void choosePay(Scanner scanner, long orderId) {
        System.out.println("直接支付(y or n)");
        if ("y".equals(scanner.next())) {
            // 修改订单状态
            orderService.changeOrderStatus(orderId, OrderConstant.PAYED_NOT_DELIVER);
            System.out.println("店家已收到通知,你的订单很快就会送到");
        }
    }

    // 执行签收订单
    private void doConfirmOrder(Scanner scanner) {
        boolean isContinued = showOrders(OrderConstant.PAYED_ON_THE_WAY, scanner);
        if (isContinued) {
            System.out.println("请选择您要签收的订单,按0返回");
            long orderId = scanner.nextLong();
            // 输入0返回
            if (orderId == 0) {
                return;
            }
            orderService.changeOrderStatus(orderId, OrderConstant.PAYED_CHECKED);
            System.out.println("您的订单已签收,欢迎继续购买");
        } else {
            System.out.println("您暂无需要签收的订单");
        }
        printFooter();
        block(scanner);
    }

    private void doOrderFood(Scanner scanner) {
        // 打印全部商家信息
        printAllShop();
        // 选择一家商店
        Shop shop = chooseShop(scanner);
        // 打印该商家的商品
        printShopItems(shop);
        // 开始订餐
        List<OrderItem> orderItemList = doChooseItem(scanner);
        // 创建订单和以及相应订单项
        long orderId = orderService.createFoodOrder(currentUser, shop, orderItemList);
        // 打印订单项详情
        printOrderDetail(orderItemList);
        // 咨询用户是否支付
        choosePay(scanner, orderId);
        printFooter();
        block(scanner);
    }
}
